package com.renne.email.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.renne.common.exception.ServiceException;
import com.renne.common.utils.StringUtils;
import com.renne.common.utils.bean.BeanValidators;
import com.renne.common.utils.file.FileUtils;
import com.renne.common.utils.poi.ExcelUtil;
import com.renne.email.domain.*;
import com.renne.email.mapper.MailItemMapper;
import com.renne.email.mapper.MailSenderConfigMapper;
import com.renne.email.service.IMailItemService;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.renne.common.utils.DateUtils;
import com.renne.common.utils.SecurityUtils;
import com.renne.common.core.domain.entity.SysUser;
import com.renne.common.core.domain.model.LoginUser;
import com.renne.common.utils.uuid.IdUtils;
import com.renne.common.utils.bean.BeanUtils;
import com.renne.common.core.text.Convert;
import com.renne.email.mapper.MailImportHistoryMapper;
import com.renne.email.service.IMailImportHistoryService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Validator;


/**
 * 邮件导入历史记录Service业务层处理
 *
 * @author LiuYu
 * @date 2024-07-26
 */
@Service
public class MailImportHistoryServiceImpl implements IMailImportHistoryService {

    private static final Logger log = LoggerFactory.getLogger(MailImportHistoryServiceImpl.class);

    @Autowired
    private MailImportHistoryMapper mailImportHistoryMapper;

    @Autowired
    private MailItemMapper mailItemMapper;

    @Autowired
    private IMailItemService mailItemService;

    @Autowired
    protected Validator validator;

    /**
     * 查询邮件导入历史记录
     *
     * @param mailImportHistoryId 邮件导入历史记录ID
     * @return 邮件导入历史记录
     */
    @Override
    public MailImportHistoryVo getMailImportHistoryVoById(String mailImportHistoryId) {
        return mailImportHistoryMapper.selectMailImportHistoryVoById(mailImportHistoryId);
    }

    /**
     * 查询邮件导入历史记录列表
     *
     * @param query 邮件导入历史记录
     * @return 邮件导入历史记录集合
     */
    @Override
    public List<MailImportHistoryVo> getMailImportHistoryVoList(MailImportHistoryQuery query) {
        return mailImportHistoryMapper.selectMailImportHistoryVoList(query);
    }

    /**
     * 新增邮件导入历史记录
     *
     * @param mailImportHistoryVo 邮件导入历史记录Vo
     * @return 结果
     */
    @Override
    public int saveMailImportHistoryVo(MailImportHistoryVo mailImportHistoryVo) {
        MailImportHistory mailImportHistory = new MailImportHistory();
        BeanUtils.copyBeanProp(mailImportHistory, mailImportHistoryVo);
        mailImportHistory.setMailImportHistoryId(IdUtils.fastSimpleUUID());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        mailImportHistory.setDeptId(sysUser.getDeptId());
        mailImportHistory.setCreateById(SecurityUtils.getUserId());
        mailImportHistory.setCreateBy(SecurityUtils.getUsername());
        mailImportHistory.setCreateTime(DateUtils.getNowDate());
        return mailImportHistoryMapper.insertMailImportHistory(mailImportHistory);

    }

    /**
     * 修改邮件导入历史记录
     *
     * @param mailImportHistoryVo 邮件导入历史记录Vo
     * @return 结果
     */
    @Override
    public int updateMailImportHistoryVo(MailImportHistoryVo mailImportHistoryVo) {
        MailImportHistory mailImportHistory = new MailImportHistory();
        BeanUtils.copyBeanProp(mailImportHistory, mailImportHistoryVo);
        mailImportHistory.setUpdateBy(SecurityUtils.getUsername());
        mailImportHistory.setUpdateTime(DateUtils.getNowDate());
        return mailImportHistoryMapper.updateMailImportHistory(mailImportHistory);
    }

    /**
     * 删除邮件导入历史记录对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteMailImportHistoryByIds(String ids) {
        return mailImportHistoryMapper.deleteMailImportHistoryByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除邮件导入历史记录信息
     *
     * @param mailImportHistoryId 邮件导入历史记录ID
     * @return 结果
     */
    @Override
    public int deleteMailImportHistoryById(String mailImportHistoryId) {
        return mailImportHistoryMapper.deleteMailImportHistoryById(mailImportHistoryId);
    }

    /**
     * 删除邮件导入历史记录信息
     *
     * @param mailImportHistoryId 邮件导入历史记录ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteMailImportHistoryByIds(String[] mailImportHistoryId) {
        int i = mailImportHistoryMapper.deleteMailImportHistoryByIds(mailImportHistoryId);
        for (String id : mailImportHistoryId) {
            mailItemMapper.deleteMailItemByMailImportHistoryId(id);
        }
        return i;
    }

    /**
     * 导入邮件历史记录
     *
     * @param file 邮件导入文件
     * @return 导入结果
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public Map<String, Object> importMailHistory(MultipartFile file) throws IOException {

        ExcelUtil<MailImportVo> util = new ExcelUtil<MailImportVo>(MailImportVo.class);
        List<MailImportVo> list = util.importExcel(file.getInputStream());

        if (StringUtils.isNull(list) || list.isEmpty()) {
            throw new ServiceException("导入数据不能为空！");
        }

        // 获取文件信息
        String fileName = file.getOriginalFilename();
        String title = StringUtils.isNotBlank(fileName) ? fileName.substring(0, fileName.indexOf(".")) : "";
        long size = file.getSize();

        MailImportHistory mailImportHistory = new MailImportHistory();
        mailImportHistory.setMailImportHistoryId(IdUtils.fastSimpleUUID());
        mailImportHistory.setCode(DateUtils.dateTimeNow());
        mailImportHistory.setName(title);
        mailImportHistory.setFileName(fileName);
        mailImportHistory.setFileSize(Integer.valueOf(size + ""));

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        mailImportHistory.setDeptId(sysUser.getDeptId());
        mailImportHistory.setCreateById(SecurityUtils.getUserId());
        mailImportHistory.setCreateBy(SecurityUtils.getUsername());
        mailImportHistory.setCreateTime(DateUtils.getNowDate());

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (MailImportVo item : list) {
            try {
                BeanValidators.validateWithException(validator, item);
                MailItem mailItem = new MailItem();

                mailItem.setMailImportHistoryId(mailImportHistory.getMailImportHistoryId());
                mailItem.setTitle(item.getTitle());
                mailItem.setToEmail(item.getToEmail());
                mailItem.setCopyEmail(item.getCopyEmail());
                mailItem.setFilePath(item.getFilePath());
                mailItem.setContent(item.getContent());
                mailItem.setRemark(item.getRemark());
                // 邮件状态：2待发送，1已发送，0发送失败
                mailItem.setStatus("2");

                mailItem.setMailItemId(IdUtils.fastSimpleUUID());
                mailItem.setDeptId(sysUser.getDeptId());
                mailItem.setCreateById(SecurityUtils.getUserId());
                mailItem.setCreateBy(SecurityUtils.getUsername());
                mailItem.setCreateTime(DateUtils.getNowDate());
                mailItemMapper.insertMailItem(mailItem);

                successNum++;
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、邮件标题【" + item.getTitle() + "】和收件人地址【" + item.getToEmail() + "】导入失败：";
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");

            mailImportHistoryMapper.insertMailImportHistory(mailImportHistory);
        }


        Map<String, Object> map = new HashMap<>();
        map.put("msg", successMsg.toString());
        map.put("mailImportHistory", mailImportHistory);
        return map;
    }

    /**
     * 发送邮件
     *
     * @param mailImportHistoryId 邮件导入历史记录ID
     */
    @Override
    public void sendMailByImportHistoryId(String mailImportHistoryId) {
        MailItemQuery query = new MailItemQuery();
        query.setMailImportHistoryId(mailImportHistoryId);
        List<MailItemVo> mailItemVoList = mailItemService.getMailItemVoList(query);
        if (StringUtils.isNull(mailItemVoList) || mailItemVoList.isEmpty()) {
            throw new ServiceException("该导入历史记录没有数据！");
        } else {
            mailItemService.sendEmailByMailItem(mailItemVoList);
        }
    }

    /**
     * 发送邮件
     *
     * @param mailImportHistoryId 邮件导入历史记录ID
     */
    @Override
    public void sendMailByImportHistoryIds(String[] mailImportHistoryId) {
        for (String id : mailImportHistoryId) {
            sendMailByImportHistoryId(id);
        }
    }

    /**
     * 导入邮件模板
     */
    @Override
    public void importTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream is = MailImportHistoryServiceImpl.class.getResourceAsStream("/tpl/mail_import_template.xlsx");
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            bs.write(buffer, 0, len);
        }
        bs.flush();

        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;filename=" + FileUtils.setFileDownloadHeader(request, "邮件导入模板.xlsx"));
        IOUtils.write(bs.toByteArray(), response.getOutputStream());
        bs.close();
        log.info("文件下载完成");
    }
}
